home *** CD-ROM | disk | FTP | other *** search
/ Aminet 52 / Aminet 52 (2002)(GTI - Schatztruhe)[!][Dec 2002].iso / Aminet / dev / gg / ncurses-5.3.lha / ncurses-5.3 / tack / scan.c < prev    next >
C/C++ Source or Header  |  2002-10-24  |  6KB  |  262 lines

  1. /*
  2. ** Copyright (C) 1991, 1997 Free Software Foundation, Inc.
  3. ** 
  4. ** This file is part of TACK.
  5. ** 
  6. ** TACK is free software; you can redistribute it and/or modify
  7. ** it under the terms of the GNU General Public License as published by
  8. ** the Free Software Foundation; either version 2, or (at your option)
  9. ** any later version.
  10. ** 
  11. ** TACK is distributed in the hope that it will be useful,
  12. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. ** GNU General Public License for more details.
  15. ** 
  16. ** You should have received a copy of the GNU General Public License
  17. ** along with TACK; see the file COPYING.  If not, write to
  18. ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  19. ** Boston, MA 02111-1307, USA.
  20. */
  21. /* scan mode keyboard support */
  22.  
  23. #include <tack.h>
  24.  
  25. MODULE_ID("$Id: scan.c,v 1.2 1999/08/21 23:09:35 tom Exp $")
  26.  
  27. int scan_max;            /* length of longest scan code */
  28. char **scan_up, **scan_down, **scan_name;
  29. int *scan_tested, *scan_length, *scan_value;
  30.  
  31. static int shift_state;
  32. static char *str;
  33. static int debug_char_count;
  34.  
  35. #define SHIFT_KEY 0x100
  36. #define CONTROL_KEY 0x200
  37. #define META_KEY 0x400
  38. #define CAPS_LOCK 0x800
  39.  
  40. static const struct {
  41.     const char *name;
  42.     int type;
  43. }  scan_special[] = {
  44.     {"<shift>", SHIFT_KEY},
  45.     {"<left shift>", SHIFT_KEY},
  46.     {"<right shift>", SHIFT_KEY},
  47.     {"<control>", CONTROL_KEY},
  48.     {"<left control>", CONTROL_KEY},
  49.     {"<right control>", CONTROL_KEY},
  50.     {"<meta>", META_KEY},
  51.     {"<left meta>", META_KEY},
  52.     {"<right meta>", META_KEY},
  53.     {"<caps lock>", CAPS_LOCK},
  54.     {"<tab>", '\t'},
  55.     {"<space>", ' '},
  56.     {"<return>", '\r'},
  57.     {"<linefeed>", '\n'},
  58.     {"<formfeed>", '\f'},
  59.     {"<backspace>", '\b'},
  60.     {0, 0}
  61. };
  62.  
  63. static void
  64. scan_blanks(void)
  65. {                /* scan past the white space */
  66.     while (*str == ' ' || *str == '\t')
  67.         str++;
  68. }
  69.  
  70. static char *
  71. smash(void)
  72. {                /* convert a string to hex */
  73.     char *s, *t;
  74.     int ch, i, j;
  75.  
  76.     t = s = str;
  77.     for (i = 0; (ch = *str); str++) {
  78.         if (ch >= '0' && ch <= '9')
  79.             j = ch - '0';
  80.         else if (ch >= 'a' && ch <= 'f')
  81.             j = 10 - 'a' + ch;
  82.         else if (ch >= 'A' && ch <= 'F')
  83.             j = 10 - 'A' + ch;
  84.         else if (ch == ' ' || ch == '\t')
  85.             break;
  86.         else
  87.             continue;
  88.         if (i) {
  89.             *s |= j;
  90.             s++;
  91.         } else
  92.             *s = j << 4;
  93.         i ^= 1;
  94.     }
  95.     *s = '\0';
  96.     return t;
  97. }
  98.  
  99. void
  100. scan_init(char *fn)
  101. {                /* read the scan mode key definitions */
  102.     char *s, *sl;
  103.     FILE *fp;
  104.     int ch, i, j;
  105.     char home[512];
  106.  
  107.     if ((str = getenv("HOME")))
  108.         strcpy(home, str);
  109.     else
  110.         home[0] = '\0';
  111.     fp = NULL;
  112.     if ((str = getenv("KEYBOARD"))) {
  113.         if (!(fp = fopen(str, "r")) && home[0]) {
  114.             sprintf(temp, "%s/.scan.%s", home, str);
  115.             fp = fopen(temp, "r");
  116.         }
  117.     }
  118.     if (!fp) {
  119.         sprintf(temp, ".scan.%s", fn);
  120.         fp = fopen(temp, "r");
  121.     }
  122.     if (!fp && home[0]) {
  123.         sprintf(temp, "%s/.scan.%s", home, fn);
  124.         fp = fopen(temp, "r");
  125.     }
  126.     if (!fp) {
  127.         ptext("Unable to open scanfile: ");
  128.         ptextln(temp);
  129.         bye_kids(1);
  130.         return;
  131.     }
  132.     /*
  133.        scan file format:
  134.     
  135.     <down value> <up value> <name>
  136.     
  137.     values are in hex. <name> may be any string of characters
  138.     
  139.     */
  140.     scan_up = (char **) malloc(sizeof(char *) * MAX_SCAN);
  141.     scan_down = (char **) malloc(sizeof(char *) * MAX_SCAN);
  142.     scan_name = (char **) malloc(sizeof(char *) * MAX_SCAN);
  143.     scan_tested = (int *) malloc(sizeof(int *) * MAX_SCAN);
  144.     scan_length = (int *) malloc(sizeof(int *) * MAX_SCAN);
  145.     scan_value = (int *) malloc(sizeof(int *) * MAX_SCAN);
  146.     scan_up[0] = scan_down[0] = scan_name[0] = (char *) 0;
  147.     str = (char *) malloc(4096);    /* buffer space */
  148.     sl = str + 4000;    /* an upper limit */
  149.     scan_max = 1;
  150.     for (i = 0;;) {
  151.         for (s = str; (ch = getc(fp)) != EOF;) {
  152.             if (ch == '\n' || ch == '\r')
  153.                 break;
  154.             *s++ = ch;
  155.         }
  156.         *s++ = '\0';
  157.         if (ch == EOF)
  158.             break;
  159.         if (*str == '#' || *str == '\0')
  160.             continue;
  161.         scan_down[i] = smash();
  162.         scan_blanks();
  163.         scan_up[i] = smash();
  164.         scan_blanks();
  165.         scan_name[i] = str;
  166.  
  167.         scan_length[i] = strlen(scan_down[i]);
  168.         ch = strlen(scan_up[i]) + scan_length[i];
  169.         if (ch > scan_max)
  170.             scan_max = ch;
  171.  
  172.         scan_value[i] = scan_name[i][0];
  173.         if (scan_name[i][1])    /* multi-character name */
  174.             for (j = 0; scan_special[j].name; j++) {
  175.                 if (!strcmp(scan_name[i], scan_special[j].name)) {
  176.                     scan_value[i] = scan_special[j].type;
  177.                     break;
  178.                 }
  179.             }
  180.  
  181.         i++;
  182.         if (str > sl) {
  183.             str = (char *) malloc(4096);
  184.             sl = str + 4000;
  185.         } else
  186.             str = s;
  187.     }
  188.     fclose(fp);
  189. #ifdef notdef
  190.     for (i = 0; scan_down[i]; i++) {
  191.         put_str(hex_expand_to(scan_down[i], 3));
  192.         put_str(hex_expand_to(scan_up[i], 3));
  193.         put_str("   ");
  194.         put_str(scan_name[i]);
  195.         put_crlf();
  196.     }
  197.     (void) wait_here();
  198. #endif
  199. }
  200.  
  201. int
  202. scan_key(void)
  203. {                /* read a key and translate scan mode to
  204.                    ASCII */
  205.     int i, j, ch;
  206.     char buf[64];
  207.  
  208.     for (i = 1;; i++) {
  209.         ch = getchar();
  210.         if (ch == EOF)
  211.             return EOF;
  212.         if (debug_fp) {
  213.             fprintf(debug_fp, "%02X ", ch);
  214.             debug_char_count += 3;
  215.             if (debug_char_count > 72) {
  216.                 fprintf(debug_fp, "\n");
  217.                 debug_char_count = 0;
  218.             }
  219.         }
  220.         buf[i - 1] = ch;
  221.         buf[i] = '\0';
  222.         if (buf[0] & 0x80) {    /* scan up */
  223.             for (j = 0; scan_up[j]; j++) {
  224.                 if (i == scan_length[j] &&
  225.                     !strcmp(buf, scan_up[j])) {
  226.                     i = 0;
  227.                     shift_state &= ~scan_value[j];
  228.                     break;
  229.                 }
  230.             }
  231.             continue;
  232.         }
  233.         for (j = 0; scan_down[j]; j++) {
  234.             if (i == scan_length[j] && !strcmp(buf, scan_down[j])) {
  235.                 i = 0;
  236.                 shift_state |= scan_value[j];
  237.                 ch = scan_value[j];
  238.                 if (ch == CAPS_LOCK)
  239.                     shift_state ^= SHIFT_KEY;
  240.                 if (ch >= 256)
  241.                     break;
  242.                 if (shift_state & SHIFT_KEY) {
  243.                     if (ch >= 0x60)
  244.                         ch -= 0x20;
  245.                     else if (ch >= 0x30 && ch <= 0x3f)
  246.                         ch -= 0x10;
  247.                 }
  248.                 if (shift_state & CONTROL_KEY) {
  249.                     if ((ch | 0x20) >= 0x60 &&
  250.                         (ch | 0x20) <= 0x7f)
  251.                         ch = (ch | 0x20) - 0x60;
  252.                 }
  253.                 if (shift_state & META_KEY)
  254.                     ch |= 0x80;
  255.                 return ch;
  256.             }
  257.         }
  258.         if (i > scan_max)
  259.             i = 1;
  260.     }
  261. }
  262.